package org.ndx.majick.ui.bool;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;

import javax.swing.AbstractButton;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.ndx.majick.properties.Property;
import org.ndx.majick.properties.VetoableProperty;

public class BooleanHandler implements ActionListener, ChangeListener, PropertyChangeListener {

	private Property<Boolean> source;
	private AbstractButton button;

	public BooleanHandler(Property<Boolean> source, AbstractButton used) {
		this.source = source;
		this.button = used;
		this.source.addPropertyChangeListener(this);
		updateAccordingToProperty();
	}

	public void actionPerformed(ActionEvent e) {
		updateModel();
	}

	public void stateChanged(ChangeEvent e) {
		updateModel();
	}

	private void updateModel() {
		if(source instanceof VetoableProperty) {
			try {
				((VetoableProperty<Boolean>) source).setVeto(button.isSelected());
			} catch (PropertyVetoException e) {
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						updateAccordingToProperty();
					}
				});
			}
		} else {
			source.set(button.isSelected());
		}
	}

	public void propertyChange(PropertyChangeEvent evt) {
		updateAccordingToProperty();
	}

	private void updateAccordingToProperty() {
		button.setSelected(source.get()!=null && source.get());
	}

	public void dispose() {
		source.removePropertyChangeListener(this);
	}
}
